﻿/*
	March 2011 - Muaz Khan - dtweet

	dtweet object is commonly used in this project
*/

var headerElement = $( 'div#header' );

var dtweet = ( function ()
{
	var prependZero = function ( v ) // just for getting dateTime - private func
	{
		v = v.toString();
		return ( v.length === 1 ) ? "0" + v : v;
	};

	/* just for trcking links in the tweet message
	Three type of links are tracked:
	1.  that starts with 'http://'
	2.  that starts with 'www'
	3.  email addresses
	*/
	var linkify = function ( inputText )
	{
		var replacedText, replacePattern1, replacePattern2, replacePattern3;

		//URLs starting with http://, https://, or ftp://
		replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
		replacedText = inputText.replace( replacePattern1, '<a href="$1" target="_blank" follow="nofollow">$1</a>' );

		//URLs starting with www. (without // before it, or it'd re-link the ones done above)
		replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
		replacedText = replacedText.replace( replacePattern2, '$1<a href="http://$2" target="_blank" follow="nofollow">$2</a>' );

		//Change email addresses to mailto:: links
		replacePattern3 = /(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim;
		replacedText = replacedText.replace( replacePattern3, '<a href="mailto:$1">$1</a>' );

		return replacedText;
	}
	return {
		exactDate: function ( dateStr ) // tracking dateTime
		{
			var dt = new Date( parseInt( dateStr.substr( 6 ), 10 ) );
			return prependZero( ( dt.getMonth() + 1 ) )
				+ "/" + prependZero( dt.getDate() )
				+ "/" + dt.getFullYear()
				+ " " + prependZero( dt.getHours() )
				+ ":" + prependZero( dt.getMinutes() )
				+ ":" + prependZero( dt.getSeconds() );
		},

		// replacing '\n' with '<br />' for rendering in html page -- linefeeds
		exactMessage: function ( inputMsg )
		{
			var arr = [];  // new empty array
			$.each(
					linkify( inputMsg ) // also tracking/inserting link in the message
					.split( '\n' ), function ( index, item )
					{
						arr += item + '<br />';
					} );
			return arr;
		},

		setMinHeight: function ()
		{
			var tweetHeight = $( '#tweets' ).height();
			$( '#main' ).css( 'min-height', tweetHeight + 70 + 'px' );
			$( '#dashboard' ).css( 'min-height', $('#mainContent').height() );
			$( "abbr.timeago" ).timeago();
		},

		// poshyTip while hovering username
		userPoshyTip: function ()
		{
			$( '.userPoshyTip' ).poshytip( {
				className: 'tip-twitter',
				alignTo: 'target',
				alignX: 'left',
				alignY: 'center',
				offsetX: 5,
				content: function ( updateCallback )
				{
					$.ajax( {
						url: domainName + '/Account/TrackUser',
						type: 'POST',
						data: "userName=" + $( this ).attr( 'id' ),
						success: function ( data )
						{
							updateCallback( '<img src="' + domainName + '/Content/images/user.gif" alt="" width="50" class="borders" style="float:left; margin-right:6px;" />'
								+ '<h2>'
								+ '<a href="' + domainName + '/user/' + data.UserName + '">' + data.FullName + '</a>'
								+ '</h2>'
								+ '<p><button id="follow" style="visibility:hidden; cursor:pointer;" title="' + data.UserName + '">follow</button>'
								+ '<small style="margin-left:0px;">Recently tweeted:</small></p>'
								+ '<div id="recentTweetMessage"></div>'
								+ '<abbr id="recentTweetTime" class="timeago"></abbr>' );

							dtweet.userFollowing( data.UserName );
							dtweet.userRecentTweet( data.UserName );

							$( 'button#follow' ).click( function ()
							{
								dtweet.followUser( $( this ).attr( 'title' ), $( this ) );
							} );
						}
					} );
					return 'Loading...';
				}
			} );
		},

		followUser: function ( userName, currentObj ) // follow public user
		{
			$.ajax( {
				url: currentObj.html() === 'follow'
						? domainName + '/Account/FollowUser'
						: domainName + '/Account/UnFollowUser',
				type: 'POST',
				data: "userName=" + userName,
				success: function ( result )
				{
					if ( result.IsSuccess === true )
					{
						if ( result.IsFollowSuccess && currentObj.html() === 'follow' )
						{
							currentObj.html( 'unfollow' );
						}
						else if ( result.IsFollowSuccess && currentObj.html() === 'unfollow' )
						{
							currentObj.html( 'follow' );
						}
					}
					if ( result.IsSuccess === false )
					{
						$( '#recentTweetTime' ).html( result.Message ).css( 'color', 'red' );
					}
				}
			} );
		},

		userRecentTweet: function ( userName ) // latest public tweet
		{
			$.ajax( {
				url: domainName + '/Tweet/UserRecentTweet',
				type: 'POST',
				data: "userName=" + userName,
				success: function ( result )
				{
					if ( result.IsSuccess === true )
					{
						$( '#recentTweetMessage' ).html( dtweet.exactMessage( result.Message ) );
						$( '#recentTweetTime' ).html( dtweet.exactDate( result.EventDate ) );
						$( '#recentTweetTime' ).attr( 'title', dtweet.exactDate( result.EventDate ) );
					}
					else
					{
						$( '#recentTweetMessage' ).html( dtweet.exactMessage( result.Message ) );
					}
					$( "abbr.timeago" ).timeago();  // timeago plugin
				}
			} );
		},

		userFollowing: function ( userName ) // following this user or not
		{
			$.ajax( {
				url: domainName + '/Account/CheckUserFollowers',
				type: 'POST',
				data: "userName=" + userName,
				success: function ( result )
				{
					if ( result.IsSuccess === true )
					{
						$( '#follow' ).css( 'visibility', 'visible' );
						if ( result.IsFollowing )
						{
							$( '#follow' ).html( 'unfollow' );
						}
					}
					if ( result.IsSuccess === false )
					{
						$( '#follow' ).css( 'visibility', 'hidden' );
					}
				},
				error: function ()
				{
					$( '#follow' ).css( 'visibility', 'hidden' );
				}
			} );
		},

		/*
		tweets to append in a table object '#tweets'
		*/
		tweetMessage: function ( data, tweetsTable )
		{
			/*
			  According to Nicholas C. Zakas:  http://www.nczonline.net
			  'Minimise document reflow by only changing the DOM when absolutely necessary'
			  http://www.youtube.com/watch?v=mHtdZgou0qU  => his presentation video
			*/
			var parentOfTable = tweetsTable.parent();
			tweetsTable.remove();
			var tweetData = data.Tweet;
			// for loop is better but .each is easier to understand and implement
			$.each(tweetData, function (index, d) {
				/*  Array.prototype.join (separator) is better than this ugly +++ for performance purpose
				however, in my opinion, below code is easier to read then if i convert it into
				Array.prototype.join (separator)
				*/
				tweetsTable.append( '<tr class="tweet"><td class="name-section"><div style="float: left; margin-left: 20px;"><img src="' + domainName + '/Content/images/user.gif" alt="" width="50" class="borders" /></div><strong>'
					+ '<a href="' + domainName + '/user/' + d.UserName + '">'
					+ d.UserName
					+ '</a>'
					+ '</strong><p><abbr class="timeago" title="'
					+ dtweet.exactDate( d.EventDate )
					+ '">'
					+ dtweet.exactDate( d.EventDate )
					+ '</abbr></p></td><td class="message-section">'
					+ dtweet.exactMessage( d.Message )
					+ '</td></tr>' );
			} );
			parentOfTable.append( tweetsTable ); // Nicholas C. Zakas' advise
		}
	};
} () );
function SearchNow()
{
	var results;
	$.ajax( {
		url: domainName + '/account/search',
		type: 'POST',
		success: function ( result )
		{
			results = result;
		}
	} ).done( function () // i am done, now you can run
	{
		$( "#SearchTerm" ).autocomplete( results, {
			minChars: 0,
			'max-width': '310px',
			matchContains: true,
			highlightItem: false,
			formatItem: function ( result )
			{
				return '<p>' + result.FullName + ' ( <i id="username">' + result.UserName + '</i>  )</p>';
			},
			formatResult: function ( result )
			{
				return result.FullName + ' ( ' + result.UserName + ' )';
			}
		} );
		function log( event, data, formatted )
		{
			if ( data )
			{
				location = domainName + '/user/' + $( formatted ).find( 'i' ).html();
			}
		}

		/*	it is better to use 'input:text' instead of ':text' according to paul irish	*/
		$( "input:text" ).result( log ).next().click( function ()
		{
			$( this ).prev().search();
		} );

	} );
}

$( window ).load( function ()
{
	$( "abbr.timeago" ).timeago();
	$( 'button' ).parent( 'a' ).addClass( 'button' ); // preventing border bottom of anchor element
	dtweet.userPoshyTip();
} );
function loginChecker( e )  // when user clicks 'login' button
{
	var loginForm = $( '#loginForm' );

	/*
		According to Nicholas C. Zakas:  http://www.nczonline.net
		'Don’t use inline styles unless you’re animating'
		http://www.youtube.com/watch?v=mHtdZgou0qU  => his presentation video
	*/
	loginForm.block( { message: 'Validating...', css: { border: 'none', padding: '15px', backgroundColor: '#000', '-webkit-border-radius': '10px', '-moz-border-radius': '10px', opacity: .5, color: '#fff', 'font-size':'20px'} } );

	var userName        = $( '#UserName' ),
		userPassword    = $( '#Password' ),
		userNameVal     = userName.val(),
		passwordVal     = userPassword.val(),
		errorMessage    = $( '#login-error-message' ),
		loginButton     = $( '#loginbtn' );

	if ( userNameVal.length < 1 )
	{
		userName.focus();
		errorMessage.addClass( 'result-error' ).html( "Enter your user name." );
		loginForm.unblock();
		loginButton.fadeIn( 'slow' );
		e.preventDefault();
		return; // return undefined;
	}
	if ( passwordVal.length < 1 )
	{
		userPassword.focus();
		errorMessage.addClass( 'result-error' ).html( "Enter your password." );
		loginForm.unblock();
		loginButton.fadeIn( 'slow' );
		e.preventDefault();
		return; // return undefined;
	}
	$.ajax( {
		url: domainName + '/Account/LoginChecker',
		type: 'POST',
		data: "username=" + userNameVal + "&password=" + passwordVal,
		success: function ( result )
		{
			if ( result.IsSuccess === false )
			{
				userName.focus();
				errorMessage.addClass( 'result-error' ).html( result.Message );
				loginForm.unblock();
				loginButton.fadeIn( 'slow' );
				e.preventDefault();
				return;  // return undefined;
			}
			if ( result.IsSuccess === true )
			{
				location = domainName + '/user/' + result.Message;
			}
		}
	} );
}

$( '#logIn' ).click( function ( e )  // login menu click
{
	e.preventDefault();
	$.ajax( {
		url: domainName + '/html/log-in.htm',
		success: function ( data )
		{
			$( '#loginFormContainer' ).html( data );
		}
	} ).done( function ()
	{
		/*
		According to Nicholas C. Zakas:  http://www.nczonline.net
		'Don’t use inline styles unless you’re animating'
		http://www.youtube.com/watch?v=mHtdZgou0qU  => his presentation video
		*/
		headerElement.block( { message: $( '#loginForm' ), css: { width: '46%'} } ).addClass( 'inside-login' );

		$( '#UserName' ).focus(); // by default, username should focus in login block

		$( '.close' ).click( function () // jquery.blockUI.js
		{
			headerElement.unblock();
		} );

		$( '#loginbtn' ).click( function ( e ) // login button click event
		{
			e.preventDefault();
			$( this ).fadeOut();
			loginChecker( e );
		} );
	} );
} );

$( '#btnSearch' ).click( function ( e ) // search menu click
{
	e.preventDefault();
	$.ajax( {
		url: domainName + '/html/Search.htm',
		success: function ( data )
		{
			$( '#loginFormContainer' ).html( data );
		}
	} ).done( function ()
	{
		headerElement.block( { message: $( '#search-form' ), css: { width: '42%'} } ).addClass( 'inside-login' );

		$( '#SearchTerm' ).focus();

		$( '.close' ).click( function ()  // jquery.blockUI.js
		{
			headerElement.unblock();
		} );
		SearchNow();
	} );
} );